---
type: tutorial
title: 'De vuelta a tierra firme. Lleva tu blog del día a la noche, ¡sin necesidad de islas!'
i18nReady: true
description: |-
  Tutorial: Crea tu primer blog con Astro —
  Crea un alternador de tema claro/oscuro utilizando sólo JavaScript y CSS
---
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

Ahora que puedes construir islas de Astro para elementos interactivos, ¡no olvides que puedes llegar bastante lejos con solo JavaScript y CSS básicos!

Vamos a crear un icono en el que se pueda hacer clic para que los usuarios puedan alternar entre los modos claro y oscuro utilizando otra etiqueta `<script>` para la interactividad... sin enviar JavaScript al navegador.

<PreCheck>
  - Crear un alternador interactivo con sólo JavaScript y CSS
  - Enviar la menor cantidad posible de JavaScript al navegador.
</PreCheck>

## Añade y estiliza un icono de cambio de tema

<Steps>
1. Crea un nuevo archivo en `src/components/ThemeIcon.astro` y pega el siguiente código en él:

    ```astro title="src/components/ThemeIcon.astro"
    ---
    ---
    <button id="themeToggle" aria-label="Toggle theme">
      <svg aria-hidden="true" width="30px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
        <path class="sun" fill-rule="evenodd" d="M12 17.5a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm0 1.5a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm12-7a.8.8 0 0 1-.8.8h-2.4a.8.8 0 0 1 0-1.6h2.4a.8.8 0 0 1 .8.8zM4 12a.8.8 0 0 1-.8.8H.8a.8.8 0 0 1 0-1.6h2.5a.8.8 0 0 1 .8.8zm16.5-8.5a.8.8 0 0 1 0 1l-1.8 1.8a.8.8 0 0 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM6.3 17.7a.8.8 0 0 1 0 1l-1.7 1.8a.8.8 0 1 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM12 0a.8.8 0 0 1 .8.8v2.5a.8.8 0 0 1-1.6 0V.8A.8.8 0 0 1 12 0zm0 20a.8.8 0 0 1 .8.8v2.4a.8.8 0 0 1-1.6 0v-2.4a.8.8 0 0 1 .8-.8zM3.5 3.5a.8.8 0 0 1 1 0l1.8 1.8a.8.8 0 1 1-1 1L3.5 4.6a.8.8 0 0 1 0-1zm14.2 14.2a.8.8 0 0 1 1 0l1.8 1.7a.8.8 0 0 1-1 1l-1.8-1.7a.8.8 0 0 1 0-1z"/>
        <path class="moon" fill-rule="evenodd" d="M16.5 6A10.5 10.5 0 0 1 4.7 16.4 8.5 8.5 0 1 0 16.4 4.7l.1 1.3zm-1.7-2a9 9 0 0 1 .2 2 9 9 0 0 1-11 8.8 9.4 9.4 0 0 1-.8-.3c-.4 0-.8.3-.7.7a10 10 0 0 0 .3.8 10 10 0 0 0 9.2 6 10 10 0 0 0 4-19.2 9.7 9.7 0 0 0-.9-.3c-.3-.1-.7.3-.6.7a9 9 0 0 1 .3.8z"/>
      </svg>
    </button>

    <style>
      #themeToggle {
        border: 0;
        background: none;
      }
      .sun { fill: black; }
      .moon { fill: transparent; }

      :global(.dark) .sun { fill: transparent; }
      :global(.dark) .moon { fill: white; }
    </style>
    ```

2. Importa y agrega el componente `<ThemeIcon />` en `Header.astro` para que se muestre en todas las páginas. Envuelve tanto `<ThemeIcon />` como `<Menu />` dentro de un `<div>` para agruparlos y poder aplicarles estilos, y agrega la etiqueta `<style>` como se muestra a continuación para algunos estilos básicos que mejoren el diseño.

    ```astro title="src/components/Header.astro" ins={4,8-9,11,16-21}
    ---
    import Menu from './Menu.astro';
    import Navigation from './Navigation.astro';
    import ThemeIcon from './ThemeIcon.astro';
    ---
    <header>
      <nav>
        <div>
          <ThemeIcon />
          <Menu />
        </div>
        <Navigation />
      </nav>
    </header>

    <style>
      div {
        display: flex;
        justify-content: space-between;
      }
    </style>
    ```

3. Visita la vista previa de tu navegador en `http://localhost:4321` para ver el icono ahora en todas tus páginas. Puedes intentar hacer clic en él, pero aún no has escrito un script para hacerlo interactivo.
</Steps>

## Añade estilos CSS para un tema oscuro

Elige algunos colores alternativos para usar en modo oscuro.

<Steps>
1. En `global.css`, define algunos estilos oscuros. Puedes elegir los tuyos propios o copiar y pegar:

    ```css title="src/styles/global.css"
    html.dark {
      background-color: #0d0950;
      color: #fff;
    }

    .dark .menu {
      background-color: #fff;
      color: #000;
    }

    .dark .nav-links a:hover,
    .dark .nav-links a:focus {
      color: #0d0950;
    }

    .dark .nav-links a {
      color: #fff;
    }

    .dark a {
      color: #ff9776;
    }
    ```
</Steps>

:::[Verificar los colores para accesibilidad]
Cuando actualices tu sitio para incluir el modo oscuro, es posible que algunos colores utilizados necesiten ajustes.

Siempre revisa tu sitio renderizado al agregar nuevos estilos y colores, y realiza los ajustes necesarios. Esto puede implicar agregar más reglas CSS `.dark` para mostrar estilos diferentes en modo oscuro, o actualizar algunos colores para que funcionen igualmente bien en ambos temas.

Considera usar herramientas de accesibilidad, como un verificador de contraste, al crear un conjunto de colores para tu sitio. También puedes ejecutar una revisión en tu sitio web con una extensión de navegador para detectar posibles problemas.
:::

## Añade interactividad en el lado del cliente

Para añadir interactividad a un componente de Astro, puedes utilizar una etiqueta `<script>`. Este script puede comprobar y establecer el tema actual desde `localStorage` y alternar el tema cuando se hace clic en el icono. 

<Steps>
1. Añade la siguiente etiqueta `<script>` en `src/components/ThemeIcon.astro` después de tu etiqueta `<style>`:

    ```astro title="src/components/ThemeIcon.astro" ins={9-38}
    <style>
      .sun { fill: black; }
      .moon { fill: transparent; }

      :global(.dark) .sun { fill: transparent; }
      :global(.dark) .moon { fill: white; }
    </style>

    <script is:inline>
      const theme = (() => {
        const localStorageTheme = localStorage?.getItem("theme") ?? '';
        if (['dark', 'light'].includes(localStorageTheme)) {
          return localStorageTheme;
        }
        if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
          return 'dark';
        }
          return 'light';
      })();
          
      if (theme === 'light') {
        document.documentElement.classList.remove('dark');
      } else {
        document.documentElement.classList.add('dark');
      }

      window.localStorage.setItem('theme', theme);

      const handleToggleClick = () => {
        const element = document.documentElement;
        element.classList.toggle("dark");
        
        const isDark = element.classList.contains("dark");
        localStorage.setItem("theme", isDark ? "dark" : "light");
      }

      document.getElementById("themeToggle")?.addEventListener("click", handleToggleClick);
    </script>
    ```

2. Comprueba la vista previa de tu navegador en `http://localhost:4321` y haz clic en el icono del tema. Comprueba que puedes cambiar entre los modos claro y oscuro.
</Steps>

<Box icon="question-mark">

### Pon a prueba tus conocimientos

Elige si cada una de las siguientes afirmaciones describe etiquetas de Astro `<script>`, componentes del framework UI, o ambos.

1. Te permiten incluir elementos de UI interactivos en tu sitio web.

    <MultipleChoice>
      <Option>
        Etiquetas `<script>` de Astro
      </Option>
      <Option>
        Componentes de frameworks de UI
      </Option>
      <Option isCorrect>
        Ambas opciones
      </Option>
    </MultipleChoice>

2. Los elementos crearán contenido estático en tu sitio a menos que incluyas un `client:` para enviar tu JavaScript al cliente y ejecutarlo en el navegador.

    <MultipleChoice>
      <Option>
       Etiquetas `<script>` de Astro
      </Option>
      <Option isCorrect>
        Componentes de frameworks de UI
      </Option>
      <Option>
        Ambas opciones
      </Option>
    </MultipleChoice>

3. Te permiten "probar" un nuevo framework sin necesidad de iniciar un proyecto completamente nuevo con esa pila tecnológica.

    <MultipleChoice>
      <Option>
        Etiquetas `<script>` de Astro
      </Option>
      <Option isCorrect>
        Componentes de frameworks de UI
      </Option>
      <Option>
        Ambas opciones
      </Option>
    </MultipleChoice>

4. Te permiten reutilizar el código que se ha escrito en otros frameworks y, a menudo, basta con soltarlos directamente en el sitio.

    <MultipleChoice>
      <Option>
        Etiquetas `<script>` de Astro
      </Option>
      <Option isCorrect>
        Componentes de frameworks de UI
      </Option>
      <Option>
        Ambas opciones
      </Option>
    </MultipleChoice>

5. Te permiten añadir interactividad sin necesidad de conocer o aprender otros frameworks de JavaScript.

    <MultipleChoice>
      <Option isCorrect>
        Etiquetas `<script>` de Astro
      </Option>
      <Option>
        Componentes de frameworks de UI
      </Option>
      <Option>
        Ambas opciones
      </Option>
    </MultipleChoice>
</Box>

<Box icon="check-list">

## Checklist

<Checklist>
- [ ] Puedo utilizar JavaScript para la interactividad cuando no quiero añadir un framework.
</Checklist>
</Box>

### Recursos

- [Script del lado del cliente `<script>` en Astro](/es/guides/client-side-scripts/)
